package com.appspot.categoryeditor.resource;

import java.io.IOException;
import java.io.OutputStream;
import java.security.Principal;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.StreamingOutput;

import org.codehaus.jackson.map.ObjectMapper;
import org.slim3.datastore.Datastore;

import com.appspot.categoryeditor.jsonbean.categorygroup.CategoryBean;
import com.appspot.categoryeditor.jsonbean.categorygroup.FolderBean;
import com.appspot.categoryeditor.jsonbean.categorygroup.FoldersBean;
import com.appspot.categoryeditor.meta.CategoryMeta;
import com.appspot.categoryeditor.meta.FolderMeta;
import com.appspot.categoryeditor.meta.UserMeta;
import com.appspot.categoryeditor.model.Category;
import com.appspot.categoryeditor.model.Folder;
import com.google.appengine.api.datastore.Key;
import com.sun.jersey.api.view.Viewable;

public class CategoriesResourceImpl extends AbstractResource implements
		CategoriesResource {

	final static UserMeta userMeta = UserMeta.get();
	final static FolderMeta folderMeta = FolderMeta.get();
	final static CategoryMeta categoryMeta = CategoryMeta.get();

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.appspot.categoryeditor.resource.UserResource#getCategories(javax.
	 * servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse,
	 * java.lang.String)
	 */
	public StreamingOutput getUserCategories(HttpServletRequest req,
			HttpServletResponse resp, String userId) {
		// try {
		// if (!checkLogin(req)) {
		// resp.sendError(403);
		// } else {
		// if (!checkAuthority(req, resp, userId)) {
		// resp.sendError(403);
		// }
		// }
		// } catch (IOException e) {
		// }

		List<Folder> foldersModel = getFoldersModel(userId);

		// Bean for JSON
		final FoldersBean foldersBean = getFoldersBeanFromModels(foldersModel);

		return new StreamingOutput() {
			@Override
			public void write(OutputStream output) throws IOException,
					WebApplicationException {
				ObjectMapper objectMapper = new ObjectMapper();
				objectMapper.writeValue(output, foldersBean);
			}
		};
	}

	@Override
	public StreamingOutput getUserPage(HttpServletRequest req,
			HttpServletResponse resp, String userId) {

		// return Response.ok(new Viewable("/category")).build();
		
		return new JspPage("/jsp/category.jsp", req, resp);
		
	}

	@Override
	public Response getCategory(HttpServletRequest req,
			HttpServletResponse resp, String id, String categoryId) {
		return Response.ok(new Viewable("/category", null)).build();
	}

	/**
	 * 権限があるかを確認
	 * 
	 * @param req
	 * @return
	 */
	protected static boolean checkAuthority(HttpServletRequest req,
			HttpServletResponse resp, String resourceUserId) {

		Principal principal = req.getUserPrincipal();
		String name = principal.getName();

		return name.startsWith(resourceUserId);
	}

	private List<Folder> getFoldersModel(String id) {
		Key key = Datastore.createKey(userMeta, id);
		List<Folder> foldersModel = Datastore
				.query(folderMeta, key)
				.sort(folderMeta.order.asc)
				.asList();
		return foldersModel;
	}

	private FoldersBean getFoldersBeanFromModels(List<Folder> foldersModel) {

		FoldersBean foldersBean = new FoldersBean();
		for (Folder folderModel : foldersModel) {
			FolderBean folderBean = new FolderBean();
			folderBean.setId(String.valueOf(folderModel.getId().getName()));
			folderBean.setOrder(folderModel.getOrder());

			List<Category> categoriesModel = folderModel
					.getCategoriesRefs()
					.getModelList();

			for (Category categoryModel : categoriesModel) {
				CategoryBean categoryBean = new CategoryBean();
				categoryBean.setId(String.valueOf(categoryModel
						.getId()
						.getName()));
				categoryBean.setContent(categoryModel.getContent());
				categoryBean.setOrder(categoryModel.getOrder());
				folderBean.addCategory(categoryBean);
			}

			foldersBean.add(folderBean);
		}
		return foldersBean;
	}
}
